package com.wocao.admin.controller;

import com.wocao.commom.model.UserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.security.SecurityConfig;
import org.apache.catalina.security.SecurityUtil;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 流程定义控制类
 *
 * @author sunhao
 * @date 2021/11/2
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@RestController
@RequestMapping("/flowable")
@Api(tags = "flowable文档")
@Slf4j
public class FlowDefinitionController {

    @Resource
    protected RepositoryService repositoryService;

    @Resource
    protected RuntimeService runtimeService;

    @Resource
    protected IdentityService identityService;

    @Resource
    protected TaskService taskService;

    @Resource
    protected HistoryService historyService;

    @Resource
    protected ManagementService managementService;

    @Resource
    protected ProcessEngine processEngine;

    // 部署流程定义
    @GetMapping("/deploy")
    @ApiOperation(value = "部署流程定义", notes = "部署流程定义")
    public String deploy() throws FileNotFoundException {
        // String path = "C://Users//sunhao//Desktop//aa//qjlc.bpmn20.xml";
        String path = "C://Users//sunhao//Desktop//aa//wocao.bpmn20.xml";
        InputStream in = new FileInputStream(path);
        Deployment deploy = repositoryService.createDeployment().addInputStream("wocao.bpmn20.xml", in).name("wocao").category("OA").deploy();
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
        repositoryService.setProcessDefinitionCategory(definition.getId(), "OA");
        return "流程定义:" + definition.getKey() + "-" + definition.getId();
    }

    // 新增一个流程实例
    @GetMapping("/add")
    @ApiOperation(value = "新增流程实例", notes = "新增流程实例")
    public String add(String userId){
        String loginUsername = getLoginUsername();
        Map<String, Object> map = new HashMap<>();
        map.put("type", "wocao");
        map.put("userId", userId);
        map.put("time", new Date());
        // 启动流程实例
        ProcessInstance wocao = runtimeService.startProcessInstanceByKey("wocao", map);
        if (wocao == null) {
            return "启动流程实例失败";
        }
        // 设置发起人到流程中
        identityService.setAuthenticatedUserId(userId);
        // 查询一下任务
        Task task = taskService.createTaskQuery().processInstanceId(wocao.getProcessInstanceId()).singleResult();
        if (task == null) {
            return "流程生成任务失败";
        }
        return "wocao的实例ID:" + wocao.getProcessInstanceId() + "  |||  任务ID:" + task.getId();
    }

    // 获取当前登录用户ID
    @GetMapping("/getLoginUser")
    @ApiOperation(value = "获取当前登录用户ID", notes = "获取当前登录用户ID")
    public String getLoginUser(){
        String loginUsername = getLoginUsername();
        String userId = Authentication.getAuthenticatedUserId();
        return userId;
    }

    // 审批流程实例
    @GetMapping("/complete")
    @ApiOperation(value = "审批流程实例", notes = "审批流程实例")
    public String complete(String taskId, String cUserId){
        String loginUsername = getLoginUsername();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            return "任务不存在";
        }
        if (!StringUtils.equals(cUserId, task.getAssignee())) {
            return "您无权审批此单子";
        }
        taskService.addComment(taskId, task.getProcessInstanceId(), "审批通过");
        taskService.complete(taskId);
        return "审批成功";
    }



    /**
     * 功能描述: 获取登录用户<br>
     *
     * @return org.iot.model.UserModel
     * @author eggg 2021/6/16 16:16
     * @see [相关类/方法]（可选）
     * @since [产品/模块版本]（可选）
     */
    public UserModel getLoginUser1() {
        try {
            SecurityContext context = SecurityContextHolder.getContext();
            org.springframework.security.core.Authentication authentication = context.getAuthentication();
            Object principal = authentication.getPrincipal();
            // 没有登录的时候,authentication并不是空
            if (principal instanceof UserDetails) {
                return (UserModel) authentication.getPrincipal();
            }
        } catch (Exception e) {
            log.error("SysLoginBusiness.getLoginUser", e);
        }
        return null;
    }

    /**
     * 获取登录用户名
     */
    private String getLoginUsername() {
        UserModel userModel = getLoginUser1();
        if (userModel != null) {
            return userModel.getUsername();
        }
        return null;
    }

}
